<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.id">
      <dt>{{item.name}}</dt>
      <dd>
        <template v-for="val in item.values" :key="val.name">
          <img :class="{selected:val.selected}"  v-if="val.picture"  :src="val.picture" @click="clickSpecs(item,val)" alt=""/>
          <span :class="{selected:val.selected}" v-else @click="clickSpecs(item,val)">{{val.name}}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import {ref} from 'vue'
import powerSet from '@/vender/power-set'

const spliter = '★'
// 得到一个路径字典对象
const getPathMap = (skus) => {
  // 1. 得到所有的sku集合  props.goods.skus
  // 2. 从所有的sku中筛选出有效的sku
  // 3. 根据有效的sku使用power-set算法得到子集
  // 4. 根据子集往路径字典对象中存储 key-value
  const pathMap = {}
  if(skus){
      skus.forEach(sku => {
      if (sku.inventory > 0) {
        // 计算当前有库存的sku的子集
        // 例如：[1,2,3] ==> [[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
        // 可选值数组
        const valueArr = sku.specs.map(val => val.valueName)
        // 可选值数组 子集
        const valueArrPowerSet = powerSet(valueArr)
        // 遍历子集，往pathMap插入数据
        valueArrPowerSet.forEach(arr => {
          // 根据arr得到字符串的key，约定key是：['蓝色','美国'] ===> '蓝色★美国'
          const key = arr.join(spliter)
          // 给pathMap设置数据
          if (pathMap[key]) {
            pathMap[key].push(sku.id)
          } else {
            pathMap[key] = [sku.id]
          }
        })
      }
    })
  }
  return pathMap
}
const getSelectedVal=(specs)=>{
  const arr =[]
  if(specs){
    specs.forEach(item=>{
      // 选中的按钮对象
      const selectedVal =item.values.find(v=>v.selected)
      arr.push(selectedVal?selectedVal.name:undefined)
    })
  }
  return arr
}
// 更新禁用状态的按钮
// 什么时候执行？1.初始化 2.点击选择规格参数时
const updateDisabledStatus = (specs,pathMap)=>{
  if(specs){
    // 1约定禁用状态为disabled
    specs.forEach((item,i)=>{
      const selectedVal=getSelectedVal(specs)
      item.values.forEach(val=>{
        // 遍历判断 按钮是否禁用 --拿当前的每一项去数据字典中找，有就可以点击，没有就禁用
        // 2判断当前是否选中，选中不要判断
        if(val.selected) return 
        // 3拿当前的值按照套入选中值的数组
        selectedVal[i]=val.name
        // 4过滤undefind 按照分隔符拼接key
        const key = selectedVal.filter(item=>item).join(spliter)
        // 5拿着key区数据字典查找是否有这样的数据,没有就禁用（true）
        val.disabled = !pathMap[key]
      })
    })
  }
}

// 初始化选中状态
const initSelectedStatus = (goods, skuId) => {
  // console.log('/',skuId);
  
  // 1. 找出sku的信息
  // 2. 遍历每一个按钮，按钮的值和sku记录的值相同，就选中。
 if(goods &&  goods.specs && goods.skus){
    const sku = goods.skus.find(sku => sku.id === skuId)
    // console.log('sku',sku);
    if(sku){
      goods.specs.forEach((item, i) => {
      // console.log('item',item);
      const val = item.values.find(val => val.name === sku.specs[i].valueName)
      val.selected = true
  })
    }
 }
}
export default {
  name: 'XtxSku',
  props:{
    goods:{
        type:Object,
        default:()=>({ specs: [], skus: [] })
    },
    skuId:{
      type:String,
      default:''
    }

  },
  setup(props,{emit}){
     const pathMap = getPathMap(props.goods.skus)
     // console.log('props.goods.skus',props.goods);
     updateDisabledStatus(props.goods.specs,pathMap)
     // console.log('pathMap',pathMap);
     if(props.skuId){
       initSelectedStatus(props.goods, props.skuId)
     }
    
    const clickSpecs=(item,val)=>{
      // 当按钮为禁用状态 阻止程序
      if(val.disabled) return
      //当前选中与不选中
      if(val.selected){
        val.selected=false
        // console.log('item',val);
      }else{
        //选其他 把全部编程不选中 再把自身编程选中状态
        item.values.forEach((res)=>{
          res.selected=false
        })
          val.selected=true
      }
      // 点击按钮 更新按钮禁用状态
      // console.log('getSelectedVal',getSelectedVal(props.goods.specs));
      updateDisabledStatus(props.goods.specs,pathMap)
      // 将你选择的sku信息通知父组件{skuId,price,oldPrice,inventory,specsText}
      // 1. 选择完整的sku组合按钮，才可以拿到这些信息，提交父组件
      // 2. 不是完整的sku组合按钮，提交空对象父组件
       const validSelectedValues = getSelectedVal(props.goods.specs).filter(v => v)
       if(validSelectedValues.length === props.goods.specs.length){
        // 完整
        const skuIds = pathMap[validSelectedValues.join(spliter)]
        const sku = props.goods.skus.find(sku => sku.id === skuIds[0])
        emit('change', {
          skuId: sku.id,
          price: sku.price,
          oldPrice: sku.oldPrice,
          inventory: sku.inventory,
          // 属性名：属性值 属性名1：属性值1 ... 这样的字符串
          specsText: sku.specs.reduce((p, c) => `${p} ${c.name}：${c.valueName}`, '').trim()
        })
       }else{
         //  不完整
         emit('change', {})
       }
    } 
    return {clickSpecs}
  }

}
</script>
<style lang="less" scoped>
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
